package com.hk.aspect;

import cn.hutool.core.util.StrUtil;
import com.hk.constants.OpenApiConstants;
import com.hk.enums.OuterErrorEnum;
import com.hk.annotation.OpenApiSign;
import com.hk.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 签名验证
 */
@Aspect
@Component
@Slf4j
public class OpenApiSignAspect {

    @Value("${appkey:123432}")
    private String appKey;

    @Value("${appSecret:8888}")
    private String appSecret;

    @Value("${appkeyAndAppSercret:666}")
    private String appkeyAndAppSercret;

    @Pointcut("execution(public * com.hk.controller..*.*(..))")
    public void controllerAspect(){

    }


    @Before(value = "controllerAspect()")
    public void methodBefore(JoinPoint joinpoint) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        MethodSignature methodSignature = (MethodSignature) joinpoint.getSignature();
        Method method = methodSignature.getMethod();

        OpenApiSign SignAnnotation = method.getAnnotation(OpenApiSign.class);
        if (Objects.nonNull(SignAnnotation)) {
            String inputAppKey = request.getHeader(OpenApiConstants.HEADER_APPKEY);
            String inputAppSecret = request.getHeader(OpenApiConstants.HEADER_APPSECRET);
            String inputAppkeyAndAppSercret = request.getHeader(OpenApiConstants.HEADER_APPKEYANDAPPSERCRET);

            if (StrUtil.isNotBlank(inputAppkeyAndAppSercret) && StrUtil.equals(appkeyAndAppSercret, inputAppkeyAndAppSercret)) {
                return;
            }

            checkEmptyParam(appKey, inputAppKey);
            checkParamCorrect(appKey, inputAppSecret);
            return;
        }
    }

    private void checkParamCorrect(String appKey2, String appSecret2) {
        if (!StrUtil.equals(appKey2, appKey) && !StrUtil.equals(appSecret2, appSecret)){
            log.error("OpenApiSignAspect.checkEmptyParam入参不正确");
            throw new BizException(OuterErrorEnum.PARAM_VALUE_ISERROR.getCode(), OuterErrorEnum.PARAM_VALUE_ISERROR.getMsg());
        }
    }

    private void checkEmptyParam(String appKey, String appSecret) {
        if (StrUtil.isBlank(appKey) || StrUtil.isBlank(appSecret)) {
            log.error("OpenApiSignAspect.checkEmptyParam必填参数为空");
            throw new BizException(OuterErrorEnum.PARAM_ISNULL_ERROR.getCode(), OuterErrorEnum.PARAM_ISNULL_ERROR.getMsg());
        }
    }


}

